/**
* Company: QuantaNetwork BeiJing Ltd
* Author : 张彦龙
* DateTime: Nov 27, 2008  12:12:59 PM
*/
package com.quantanetwork.esm.port;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.util.List;
import java.util.concurrent.ExecutorCompletionService;
import java.util.concurrent.Future;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.logging.Logger;

import javax.sql.DataSource;

import org.springframework.jdbc.support.rowset.SqlRowSet;

public class PortScanner
{
	public static Logger logger = Logger.getLogger(PortScanner.class.getName());

	public String TestSacnForBetterWay(String host, int startPort, int endPort, int taskNum, int timeOut, int threadNum, int type)
	{
		//testtableDAO.save();
		long start = System.currentTimeMillis();
		int threadCount = 0;
		int totalPort = endPort - startPort;
		ThreadPoolExecutor executorService = (ThreadPoolExecutor) QuantaThreadPool.newFixedThreadPool(threadNum);
		ExecutorCompletionService<Result> service = new ExecutorCompletionService<Result>(executorService);
		while (startPort < endPort)
		{
			if ((startPort + taskNum) >= endPort)
			{
				service.submit(new QuantaPortTools(host, startPort, endPort, timeOut, type));
			}
			else
			{
				service.submit(new QuantaPortTools(host, startPort, startPort + taskNum, timeOut, type));
			}
			threadCount++;
			startPort += taskNum;
		}
		long totalTime = 0l;
		int tempThreadCount = threadCount * 1000;
		long maxTime = 0l;
		long minTime = 01;
		executorService.shutdown();
		try
		{
			IdentifyMethod method = null;
			while (threadCount > 0)
			{
				Future<Result> future = service.take();
				long time = future.get().getTime();
				if (time > maxTime)
				{
					maxTime = time;
				}
				if (time < minTime)
				{
					minTime = time;
				}
				totalTime += time;
				List<Portinfo> list = future.get().getList();
				for (Portinfo portInfoBean : list)
				{
					method = IdenifyMethodFactory.getIndentify(portInfoBean.getPort());
					Portinfo newPort = method.indentify(portInfoBean.getServer(), portInfoBean.getPort(), null, portInfoBean.getType(), timeOut);
					if (newPort != null)
					{
						if (newPort.getDesc() != null && !newPort.getDesc().equals(""))
						{
							portInfoBean.setDesc(newPort.getDesc());
						}
						if (newPort.getAdvice() != null && !newPort.getAdvice().equals(""))
						{
							portInfoBean.setAdvice(newPort.getAdvice());
						}
					}
					try
					{
						SqlRowSet rowSet = SpringJDBC.getJdbc().queryForRowSet("select * from portinfo where server='" + portInfoBean.getServer() + "' and port=" + portInfoBean.getPort());
						if (rowSet.next())
						{
						}
						else
						{
							DataSource source = SpringJDBC.getJdbc().getDataSource();
							Connection conn = source.getConnection();
							PreparedStatement statement = conn.prepareStatement("INSERT INTO `portinfo` (`server`,`port`,`desc`,`type`,`advice`,`response`) VALUES (?,?,?,?,?,?)");
							statement.setString(1, portInfoBean.getServer());
							statement.setInt(2, portInfoBean.getPort());
							statement.setString(3, portInfoBean.getDesc());
							statement.setString(4, portInfoBean.getType());
							statement.setString(5, portInfoBean.getAdvice());
							statement.setString(6, portInfoBean.getResponse());
							statement.executeUpdate();
							conn.close();
						}
					}
					catch (Exception e)
					{
						e.printStackTrace();
					}
					logger.info(portInfoBean.toString());
				}
				threadCount--;
			}
		}
		catch (Exception e)
		{
		}
		long runTime = (System.currentTimeMillis() - start) / 1000;
		try
		{
			DataSource source = SpringJDBC.getJdbc().getDataSource();
			Connection conn = source.getConnection();
			PreparedStatement statement = conn.prepareStatement("INSERT INTO `testresult` (`totalPort`,`totalThread`,`taskNum`,`timeOut`,`runTime`,`avgThread`,`maxThread`,`minThread`,`desc`) VALUES (?,?,?,?,?,?,?,?,?)");
			statement.setInt(1, totalPort);
			statement.setInt(2, threadNum);
			statement.setInt(3, taskNum);
			statement.setInt(4, timeOut);
			statement.setInt(5, Integer.parseInt(runTime + ""));
			statement.setInt(6, ((Long) (totalTime / tempThreadCount)).intValue());
			statement.setInt(7, Integer.parseInt(maxTime + ""));
			statement.setInt(8, Integer.parseInt(minTime + ""));
			statement.setString(9, "任务描述: 端口数量 :" + totalPort + " 线程池数 :" + threadNum + " 单个任务数：" + taskNum + " 超时时间" + timeOut + "\n运行时间:" + runTime + "毫秒" + " 平均线程时间:" + (totalTime / tempThreadCount) + "毫秒,单线程最大时间 " + maxTime + ", 单线程最小时间:" + minTime);
			statement.executeUpdate();
			conn.close();
		}
		catch (Exception e)
		{
			e.printStackTrace();
		}
		return "任务描述: 端口数量 :" + totalPort + " 线程池数 :" + threadNum + " 单个任务数：" + taskNum + " 超时时间" + timeOut + "\n运行时间:" + (System.currentTimeMillis() - start) / 1000 + "秒" + " 平均线程时间:" + (totalTime / tempThreadCount) + "毫秒,单线程最大时间 " + maxTime + ", 单线程最小时间:" + minTime;
	}
}
